import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;

public class Main extends JFrame {
    private GamePanel gamePanel;
    
    public Main() {
        setTitle("Java塔防游戏");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        
        gamePanel = new GamePanel();
        add(gamePanel);
        
        pack();
        setLocationRelativeTo(null);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            Main game = new Main();
            game.setVisible(true);
        });
    }
}

class GamePanel extends JPanel {
    // 游戏状态管理
    public final ArrayList<Tower> towers;
    private final ArrayList<Enemy> enemies;
    private Map map;
    private boolean gameRunning;
    private int playerLives;
    private int playerMoney;
    
    // 资源管理
    private transient Image background;
    private transient Image basicTowerImg;
    private transient Image cannonTowerImg;
    private transient Image sniperTowerImg;
    public transient Image[] enemyImgs = new Image[3];
    public transient Image pathImg;
    private final Font gameFont = new Font("Arial", Font.BOLD, 16);
    
    // 建造系统
    public Tower previewTower;
    public boolean isBuilding;
    public int selectedTowerType = 0; // 0:未选 1:基础 2:加农 3:狙击
    public final Rectangle[] towerIcons;
    
    // 常量定义
    private static final int INITIAL_LIVES = 20;
    private static final int INITIAL_MONEY = 500;
    public static final Dimension GAME_SIZE = new Dimension(800, 600);
    
    public ArrayList<Tower> getTowers() {
        return towers;
    }

    public GamePanel() {
        setPreferredSize(GAME_SIZE);
        setBackground(new Color(50, 50, 50));
        
        // 初始化集合
        this.towers = new ArrayList<>();
        this.enemies = new ArrayList<>();
        this.map = new Map(this);
        
        // 初始化游戏状态
        this.gameRunning = true;
        this.playerLives = INITIAL_LIVES;
        this.playerMoney = GamePanel.INITIAL_MONEY;  // 使用类常量引用
        
        // 初始化UI组件
        this.towerIcons = new Rectangle[3];
        // 初始化防御塔图标区域
        towerIcons[0] = new Rectangle(50, 550, 80, 40);
        towerIcons[1] = new Rectangle(150, 550, 80, 40); 
        towerIcons[2] = new Rectangle(250, 550, 80, 40);
        
        try {
            // 加载图像资源
            basicTowerImg = new ImageIcon("../20250910152605/resources/tower_basic.png").getImage();
            cannonTowerImg = new ImageIcon("../20250910152605/resources/tower_cannon.png").getImage();
            sniperTowerImg = new ImageIcon("../20250910152605/resources/tower_sniper.png").getImage();
            enemyImgs[0] = new ImageIcon("../20250910152605/resources/enemy1.png").getImage();
            enemyImgs[1] = new ImageIcon("../20250910152605/resources/enemy2.png").getImage();
            enemyImgs[2] = new ImageIcon("../20250910152605/resources/enemy3.png").getImage();
            pathImg = new ImageIcon("../20250910152605/resources/path.png").getImage();
            background = null;
        } catch (Exception e) {
            System.err.println("加载资源失败: " + e.getMessage());
            background = null;
        }
        
        // 初始化防御塔图标区域
        towerIcons[0] = new Rectangle(50, 550, 80, 40);
        towerIcons[1] = new Rectangle(150, 550, 80, 40); 
        towerIcons[2] = new Rectangle(250, 550, 80, 40);
        
        previewTower = null;
        isBuilding = false;
        selectedTowerType = 0;
        
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                // 检查是否点击了防御塔图标
                if (e.getY() > 550) {
                    for (int i = 0; i < towerIcons.length; i++) {
                        if (towerIcons[i].contains(e.getPoint())) {
                            selectedTowerType = i + 1;
                            isBuilding = true;
                            previewTower = null; // 仅选择类型，不创建预览
                            repaint();
                            return;
                        }
                    }
                    return;
                }
                
                // 在地图上点击创建防御塔（智能网格对齐）
                if (isBuilding && selectedTowerType > 0) {
                    // 计算点击位置的2x2网格中心坐标
                    int gridX = (int)(e.getX() / Map.GRID_SIZE) * Map.GRID_SIZE;
                    int gridY = (int)(e.getY() / Map.GRID_SIZE) * Map.GRID_SIZE;
                    int centerX = gridX + Map.GRID_SIZE; // 2x2网格中心
                    int centerY = gridY + Map.GRID_SIZE;
                    
                    // 仅在点击的网格位置建造
                    if (!map.isBuildable(centerX, centerY)) {
                        return; // 如果点击位置不可建造则直接返回
                    }
                    
                    // 检查位置是否可用且不与现有防御塔重叠
                    if (map.isBuildable(centerX, centerY) && !map.isTowerOverlap(centerX, centerY)) {
                        switch(selectedTowerType) {
                            case 1: 
                                if (playerMoney >= 50) {
                                    Tower tower = new BasicTower(centerX, centerY);
                                    towers.add(tower);
                                    playerMoney -= 50;
                                    map.occupySpace(centerX, centerY);
                                }
                                break;
                            case 2:
                                if (playerMoney >= 100) {
                                    Tower tower = new CannonTower(centerX, centerY);
                                    towers.add(tower);
                                    playerMoney -= 100;
                                    map.occupySpace(centerX, centerY);
                                }
                                break;
                            case 3:
                                if (playerMoney >= 150) {
                                    Tower tower = new SniperTower(centerX, centerY);
                                    towers.add(tower);
                                    playerMoney -= 150;
                                    map.occupySpace(centerX, centerY);
                                }
                                break;
                        }
                        repaint();
                    }
                }
                
                // 正常建造逻辑 (排除图标区域)
                if (SwingUtilities.isLeftMouseButton(e) && isBuilding && previewTower != null && e.getY() <= 550) {
                    if (map.isBuildable(e.getX(), e.getY())) {
                        towers.add(previewTower);
                        playerMoney -= previewTower.getCost();
                    }
                    previewTower = null;
                    isBuilding = false;
                    selectedTowerType = 0;
                    repaint();
                }
            }
            @Override
            public void mouseClicked(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e) && isBuilding && map.isBuildable(e.getX(), e.getY())) {
                    if (previewTower != null) {
                        towers.add(previewTower);
                        playerMoney -= previewTower.getCost();
                        previewTower = null;
                        isBuilding = false;
                        selectedTowerType = 0;
                        repaint();
                    }
                }
            }
        });
        
        addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                if (isBuilding && selectedTowerType > 0) {
                    // 动态创建预览塔
                    if (previewTower == null) {
                        switch(selectedTowerType) {
                            case 1: previewTower = new BasicTower(e.getX(), e.getY()); break;
                            case 2: previewTower = new CannonTower(e.getX(), e.getY()); break;
                            case 3: previewTower = new SniperTower(e.getX(), e.getY()); break;
                        }
                    } else {
                        previewTower.x = e.getX();
                        previewTower.y = e.getY();
                    }
                    repaint();
                }
            }
        });
        
        new javax.swing.Timer(1000, e -> {
            if (gameRunning) {
                int yPos = 280 + (int)(Math.random() * 40);
                enemies.add(new Enemy(0, yPos, map));
                repaint();
            }
        }).start();
        
        new javax.swing.Timer(50, e -> {
            if (gameRunning) {
                repaint();
            }
        }).start();
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        if (background != null) {
            g2d.drawImage(background, 0, 0, getWidth(), getHeight(), this);
        } else {
            g2d.setColor(new Color(30, 30, 30));
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }
        
        map.draw(g2d);
        
        // 使用迭代器安全地处理敌人
        Iterator<Enemy> enemyIterator = enemies.iterator();
        while (enemyIterator.hasNext()) {
            Enemy enemy = enemyIterator.next();
            enemy.update();
            if (enemy.getHealth() <= 0) {
                enemyIterator.remove();
                playerMoney += 30;
                continue;
            }
            enemy.draw(g2d);
        }
        
        // 绘制已建造的防御塔
        for (Tower tower : towers) {
            // 绘制防御塔（已包含2x2大小）
            tower.draw(g2d);
            tower.attack(enemies);
        }
        
        // 绘制防御塔选择栏
        g2d.setColor(new Color(60, 60, 90));
        g2d.fillRect(0, 550, 800, 50);
        
        g2d.setColor(Color.WHITE);
        g2d.drawString("选择防御塔:", 10, 570);
        
        // 绘制防御塔图标
        g2d.setColor(selectedTowerType == 1 ? Color.GREEN : new Color(100, 100, 150));
        g2d.fillRect(towerIcons[0].x, towerIcons[0].y, towerIcons[0].width, towerIcons[0].height);
        g2d.setColor(Color.WHITE);
        g2d.drawString("基础塔 $50", towerIcons[0].x + 10, towerIcons[0].y + 25);
        
        g2d.setColor(selectedTowerType == 2 ? Color.GREEN : new Color(100, 100, 150));
        g2d.fillRect(towerIcons[1].x, towerIcons[1].y, towerIcons[1].width, towerIcons[1].height);
        g2d.setColor(Color.WHITE);
        g2d.drawString("加农炮 $100", towerIcons[1].x + 10, towerIcons[1].y + 25);
        
        g2d.setColor(selectedTowerType == 3 ? Color.GREEN : new Color(100, 100, 150));
        g2d.fillRect(towerIcons[2].x, towerIcons[2].y, towerIcons[2].width, towerIcons[2].height);
        g2d.setColor(Color.WHITE);
        g2d.drawString("狙击塔 $150", towerIcons[2].x + 10, towerIcons[2].y + 25);
        
        // 绘制预建的防御塔
        if (this.isBuilding && this.previewTower != null) {
            Graphics2D previewG = (Graphics2D) g2d.create();
            previewG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f));
            previewTower.draw(previewG);
            previewG.dispose();
            
            // 显示建造提示
            g2d.setColor(Color.WHITE);
            g2d.drawString("左键点击确认建造", 10, 20);
            g2d.drawString("右键取消", 10, 40);
            
            // 显示建造位置是否有效
            if (map.isBuildable(previewTower.x, previewTower.y)) {
                g2d.setColor(Color.GREEN);
                g2d.drawString("可建造", previewTower.x + 30, previewTower.y);
            } else {
                g2d.setColor(Color.RED);
                g2d.drawString("不可建造", previewTower.x + 30, previewTower.y);
            }
        }
        
        g2d.setColor(new Color(0, 0, 0, 150));
        g2d.fillRoundRect(680, 10, 110, 60, 10, 10);
        
        g2d.setFont(gameFont);
        g2d.setColor(Color.WHITE);
        g2d.drawString("生命: " + playerLives, 690, 30);
        g2d.drawString("金钱: $" + playerMoney, 690, 50);
    }
}

abstract class Tower {
    protected int x, y;
    protected int range;
    protected int damage;
    protected int cooldown;
    protected int cooldownMax;
    protected int lastAttackX;
    protected int lastAttackY;
    protected int attackFrame;
    protected int cost;
    protected Color color;
    protected String type;
    
    public Tower(int x, int y, int range, int damage, int cooldownMax, int cost, Color color, String type) {
        this.x = x;
        this.y = y;
        this.range = range;
        this.damage = damage;
        this.cooldownMax = cooldownMax;
        this.cost = cost;
        this.color = color;
        this.type = type;
        this.cooldown = 0;
        this.attackFrame = 0;
    }
    
    public abstract void draw(Graphics2D g);
    public abstract boolean attack(ArrayList<Enemy> enemies);
    
    public int getCost() {
        return cost;
    }
    
    public String getType() {
        return type;
    }
    
    protected Enemy findNearestEnemy(ArrayList<Enemy> enemies) {
        if (enemies.isEmpty()) return null;
        
        // 按距离和路径进度排序
        enemies.sort((e1, e2) -> {
            double dist1 = Math.sqrt(Math.pow(e1.getX() - x, 2) + Math.pow(e1.getY() - y, 2));
            double dist2 = Math.sqrt(Math.pow(e2.getX() - x, 2) + Math.pow(e2.getY() - y, 2));
            
            // 优先攻击距离近且路径进度高的敌人
            if (dist1 <= range && dist2 <= range) {
                return Double.compare(dist1, dist2);
            }
            return 0;
        });
        
        // 返回范围内最近的敌人
        for (Enemy enemy : enemies) {
            double dist = Math.sqrt(Math.pow(enemy.getX() - x, 2) + Math.pow(enemy.getY() - y, 2));
            if (dist <= range) {
                return enemy;
            }
        }
        return null;
    }
}

class BasicTower extends Tower {
    public BasicTower(int x, int y) {
        super(x, y, 120, 15, 10, 50, new Color(0, 150, 255), "基础塔"); // 冷却时间从20减半到10
    }
    
    @Override
    public void draw(Graphics2D g) {
        // 绘制2x2大小的防御塔
        int size = Map.GRID_SIZE * 2;
        GradientPaint gradient = new GradientPaint(
            x - size/2, y - size/2, color,
            x + size/2, y + size/2, color.brighter()
        );
        g.setPaint(gradient);
        g.fillRoundRect(x - size/2, y - size/2, size, size, 20, 20);
        
        // 绘制中心标记
        g.setColor(new Color(200, 200, 255));
        g.fillOval(x - 15, y - 15, 30, 30);
        
        if (attackFrame > 0) {
            g.setColor(Color.YELLOW);
            g.setStroke(new BasicStroke(2));
            g.drawLine(x, y, lastAttackX, lastAttackY);
            attackFrame--;
        }
        
        // 调整攻击范围显示为2x2防御塔适配
        g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 30));
        g.fillOval(x - range + Map.GRID_SIZE/2, y - range + Map.GRID_SIZE/2, range * 2 - Map.GRID_SIZE, range * 2 - Map.GRID_SIZE);
    }
    
    @Override
    public boolean attack(ArrayList<Enemy> enemies) {
        if (cooldown > 0) {
            cooldown--;
            return false;
        }
        
        Enemy target = findNearestEnemy(enemies);
        if (target != null) {
            target.setHealth(target.getHealth() - damage);
            cooldown = cooldownMax;
            
            lastAttackX = target.getX();
            lastAttackY = target.getY();
            attackFrame = 5;
            return target.getHealth() <= 0;
        }
        return false;
    }
}

class CannonTower extends Tower {
    public CannonTower(int x, int y) {
        super(x, y, 80, 35, 40, 100, new Color(200, 100, 0), "加农炮");
    }
    
    @Override
    public void draw(Graphics2D g) {
        // 绘制2x2大小的加农炮塔
        int size = Map.GRID_SIZE * 2;
        GradientPaint gradient = new GradientPaint(
            x - size/2, y - size/2, color,
            x + size/2, y + size/2, color.brighter()
        );
        g.setPaint(gradient);
        g.fillRoundRect(x - size/2, y - size/2, size, size, 30, 30);
        
        // 绘制炮管
        g.setColor(new Color(150, 150, 150));
        g.fillRect(x - 25, y - 10, 50, 20);
        
        if (attackFrame > 0) {
            g.setColor(new Color(255, 150, 0, 150));
            g.fillOval(lastAttackX - 15, lastAttackY - 15, 30, 30);
            attackFrame--;
        }
        
        g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 50));
        g.fillOval(x - range, y - range, range * 2, range * 2);
    }
    
    @Override
    public boolean attack(ArrayList<Enemy> enemies) {
        if (cooldown > 0) {
            cooldown--;
            return false;
        }
        
        Enemy target = findNearestEnemy(enemies);
        if (target != null) {
            for (Enemy enemy : enemies) {
                double dist = Math.sqrt(Math.pow(enemy.getX() - target.getX(), 2) + 
                                      Math.pow(enemy.getY() - target.getY(), 2));
                if (dist <= 40) {
                    enemy.setHealth(enemy.getHealth() - (int)(damage * (1 - dist/80)));
                }
            }
            
            boolean enemyKilled = target.getHealth() <= 0;
            cooldown = cooldownMax;
            
            lastAttackX = target.getX();
            lastAttackY = target.getY();
            attackFrame = 8;
            return enemyKilled;
        }
        return false;
    }
}

class SniperTower extends Tower {
    public SniperTower(int x, int y) {
        super(x, y, 200, 100, 60, 150, new Color(150, 0, 200), "狙击塔"); // 伤害从50提升到100
    }
    
    @Override
    public void draw(Graphics2D g) {
        // 绘制2x2大小的狙击塔
        int size = Map.GRID_SIZE * 2;
        GradientPaint gradient = new GradientPaint(
            x - size/2, y - size/2, color,
            x + size/2, y + size/2, color.brighter()
        );
        g.setPaint(gradient);
        g.fillRoundRect(x - size/2, y - size/2, size, size, 20, 20);
        
        // 绘制瞄准镜
        g.setColor(Color.WHITE);
        g.fillOval(x - 15, y - 15, 30, 30);
        g.setColor(Color.RED);
        g.fillOval(x - 5, y - 5, 10, 10);
        
        if (attackFrame > 0) {
            g.setColor(new Color(255, 0, 0, 200));
            g.setStroke(new BasicStroke(1));
            g.drawLine(x, y, lastAttackX, lastAttackY);
            attackFrame--;
        }
        
        g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 30));
        g.fillOval(x - range, y - range, range * 2, range * 2);
    }
    
    @Override
    public boolean attack(ArrayList<Enemy> enemies) {
        if (cooldown > 0) {
            cooldown--;
            return false;
        }
        
        Enemy target = findNearestEnemy(enemies);
        if (target != null) {
            target.setHealth(target.getHealth() - damage);
            boolean enemyKilled = target.getHealth() <= 0;
            cooldown = cooldownMax;
            
            lastAttackX = target.getX();
            lastAttackY = target.getY();
            attackFrame = 10;
            return enemyKilled;
        }
        return false;
    }
}

class Enemy {
    private int x, y;
    private int health;
    private int speed;
    private int maxHealth;
    private int type;
    private Color color;
    private Point targetPoint;
    private int currentPathIndex = 0;
    private final Map map;
    
    public Enemy(int x, int y, Map map) {
        this.map = map;
        this.x = x;
        this.y = y;
        this.type = (int)(Math.random() * 3);
        switch(type) {
            case 0:
                this.maxHealth = 80;
                this.speed = 2;
                this.color = new Color(200, 50, 50);
                break;
            case 1:
                this.maxHealth = 50;
                this.speed = 4;
                this.color = new Color(50, 200, 50);
                break;
            case 2:
                this.maxHealth = 150;
                this.speed = 1;
                this.color = new Color(50, 50, 200);
                break;
        }
        this.health = maxHealth;
        this.targetPoint = map.getPathPoints().get(currentPathIndex + 1);
    }
    
    public void update() {
        // 对齐网格移动
        int gridX = (int)Math.round(x / (double)Map.GRID_SIZE);
        int gridY = (int)Math.round(y / (double)Map.GRID_SIZE);
        
        // 计算目标网格坐标
        int targetGridX = (int)Math.round(targetPoint.x / (double)Map.GRID_SIZE);
        int targetGridY = (int)Math.round(targetPoint.y / (double)Map.GRID_SIZE);
        
        // 网格移动
        if (gridX < targetGridX) x += speed;
        else if (gridX > targetGridX) x -= speed;
        else if (gridY < targetGridY) y += speed;
        else if (gridY > targetGridY) y -= speed;
        
        // 到达当前目标点
        if (gridX == targetGridX && gridY == targetGridY && 
            currentPathIndex < this.map.getPathPoints().size() - 2) {
            currentPathIndex++;
            targetPoint = map.getPathPoints().get(currentPathIndex + 1);
        }
    }
    
    public void draw(Graphics2D g) {
        int size = type == 2 ? 40 : 30;
        int offset = size / 2;
        
        GradientPaint gradient = new GradientPaint(
            x - offset, y, color.brighter(),
            x + offset, y, color.darker()
        );
        g.setPaint(gradient);
        
        if (type == 1) {
            int[] xPoints = {x, x - offset, x + offset};
            int[] yPoints = {y - offset, y + offset, y + offset};
            g.fillPolygon(xPoints, yPoints, 3);
            g.setColor(color.darker().darker());
            g.drawPolygon(xPoints, yPoints, 3);
        } else {
            g.fillOval(x - offset, y - offset, size, size);
            g.setColor(color.darker().darker());
            g.drawOval(x - offset, y - offset, size, size);
        }
        
        g.setColor(Color.BLACK);
        g.fillRect(x - 20, y - offset - 10, 40, 5);
        g.setColor(new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue()));
        g.fillRect(x - 20, y - offset - 10, (int)(40 * ((double)health / maxHealth)), 5);
    }
    
    public int getX() { return x; }
    public int getY() { return y; }
    public int getHealth() { return health; }
    public void setHealth(int health) { this.health = health; }
}

class Map extends JPanel {
    public final GamePanel gamePanel;
    private final ArrayList<Point> pathPoints;
    private final ArrayList<Rectangle> buildAreas;
    private final int[][] grid;
    public static final int GRID_SIZE = 40;
    private static final int PATH_WIDTH = 40;  // 与网格大小一致

    public Map(GamePanel gamePanel) {
        super();
        this.gamePanel = gamePanel;
        
        // 初始化路径点
        this.pathPoints = new ArrayList<>(Arrays.asList(
            new Point(0, 300),
            new Point(200, 300),
            new Point(200, 150),
            new Point(500, 150),
            new Point(500, 450),
            new Point(800, 450)
        ));

        // 初始化网格
        int gridCols = (800 / GRID_SIZE) + 1;
        int gridRows = (600 / GRID_SIZE) + 1;
        this.grid = new int[gridCols][gridRows];
        initializeGrid();

        // 初始化建造区域
        this.buildAreas = initializeBuildAreas();
    }

    private void initializeGrid() {
        // 初始化所有网格为可建造状态
        for (int i = 0; i < grid.length; i++) {
            Arrays.fill(grid[i], 0);
        }

        // 标记路径网格
        for (int i = 0; i < pathPoints.size() - 1; i++) {
            markPathSegment(pathPoints.get(i), pathPoints.get(i+1));
        }
    }

    private void markPathSegment(Point p1, Point p2) {
        int x1 = (int)Math.floor(p1.x / (double)GRID_SIZE);
        int y1 = (int)Math.floor(p1.y / (double)GRID_SIZE);
        int x2 = (int)Math.floor(p2.x / (double)GRID_SIZE);
        int y2 = (int)Math.floor(p2.y / (double)GRID_SIZE);

        if (x1 == x2) { // 垂直路径
            for (int y = Math.min(y1, y2); y <= Math.max(y1, y2); y++) {
                grid[x1][y] = 1;
            }
        } else if (y1 == y2) { // 水平路径
            for (int x = Math.min(x1, x2); x <= Math.max(x1, x2); x++) {
                grid[x][y1] = 1;
            }
        }
    }

    private ArrayList<Rectangle> initializeBuildAreas() {
        Area buildableArea = new Area(new Rectangle(0, 0, 800, 600));
        buildableArea.subtract(createPathArea());
        return decomposeArea(buildableArea);
    }

    private Area createPathArea() {
        Area pathArea = new Area();
        
        for (int i = 0; i < pathPoints.size() - 1; i++) {
            Point p1 = pathPoints.get(i);
            Point p2 = pathPoints.get(i+1);

            if (p1.x == p2.x) { // 垂直路径
                int x = p1.x - PATH_WIDTH/2;
                int y = Math.min(p1.y, p2.y);
                int height = Math.abs(p2.y - p1.y) + PATH_WIDTH;
                pathArea.add(new Area(new Rectangle(x, y, PATH_WIDTH, height)));
            } else { // 水平路径
                int x = Math.min(p1.x, p2.x);
                int y = p1.y - PATH_WIDTH/2;
                int width = Math.abs(p2.x - p1.x) + PATH_WIDTH;
                pathArea.add(new Area(new Rectangle(x, y, width, PATH_WIDTH)));
            }
        }
        return pathArea;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        draw((Graphics2D)g);
    }

    public boolean isBuildable(int x, int y) {
        // 获取点击位置的网格坐标
        int gridX = (int)(x / GRID_SIZE);
        int gridY = (int)(y / GRID_SIZE);
        
        // 检查4个相邻网格是否可用
        boolean buildable = isGridBuildable(gridX, gridY) &&
                          isGridBuildable(gridX + 1, gridY) &&
                          isGridBuildable(gridX, gridY + 1) &&
                          isGridBuildable(gridX + 1, gridY + 1);
        
        // 检查是否与现有防御塔重叠
        return buildable && !isTowerOverlap(x, y);
    }
    
    public boolean isTowerOverlap(int x, int y) {
        // 计算当前防御塔的4格边界
        int left = (int)(x / GRID_SIZE);
        int top = (int)(y / GRID_SIZE);
        int right = left + 1;
        int bottom = top + 1;
        
        for (Tower tower : gamePanel.getTowers()) {
            // 计算已有防御塔的4格边界
            int tLeft = (int)(tower.x / GRID_SIZE);
            int tTop = (int)(tower.y / GRID_SIZE);
            int tRight = tLeft + 1;
            int tBottom = tTop + 1;
            
            // 精确检查矩形重叠
            if (!(right < tLeft || left > tRight || bottom < tTop || top > tBottom)) {
                return true;
            }
        }
        return false;
    }
    
    private boolean isGridBuildable(int gridX, int gridY) {
        if (gridX < 0 || gridX >= grid.length || gridY < 0 || gridY >= grid[0].length) {
            return false;
        }
        return grid[gridX][gridY] == 0;
    }

    public void occupySpace(int x, int y) {
        int gridX = (int)(x / GRID_SIZE);
        int gridY = (int)(y / GRID_SIZE);
        
        // 标记4个相邻网格为已占用
        markGridOccupied(gridX, gridY);
        markGridOccupied(gridX + 1, gridY);
        markGridOccupied(gridX, gridY + 1);
        markGridOccupied(gridX + 1, gridY + 1);
    }
    
    private void markGridOccupied(int gridX, int gridY) {
        if (gridX >= 0 && gridX < grid.length && gridY >= 0 && gridY < grid[0].length) {
            grid[gridX][gridY] = 2;
        }
    }

    private ArrayList<Rectangle> decomposeArea(Area area) {
        ArrayList<Rectangle> rects = new ArrayList<>();
        Rectangle bounds = area.getBounds();

        for (int x = bounds.x; x < bounds.x + bounds.width; x += GRID_SIZE) {
            for (int y = bounds.y; y < bounds.y + bounds.height; y += GRID_SIZE) {
                Rectangle cell = new Rectangle(x, y, GRID_SIZE, GRID_SIZE);
                if (area.intersects(cell)) {
                    rects.add(cell);
                }
            }
        }
        return rects;
    }

    public ArrayList<Point> getPathPoints() {
        return new ArrayList<>(pathPoints);
    }

    public void draw(Graphics2D g) {
        // 绘制背景
        g.setColor(new Color(30, 30, 3));
        g.fillRect(0, 0, 800, 600);

        // 绘制网格
        g.setColor(new Color(70, 70, 100, 150));
        for (int x = 0; x < 800; x += GRID_SIZE) {
            g.drawLine(x, 0, x, 600);
        }
        for (int y = 0; y < 600; y += GRID_SIZE) {
            g.drawLine(0, y, 800, y);
        }

        // 绘制建造区域
        g.setColor(new Color(50, 50, 80, 150));
        for (Rectangle area : buildAreas) {
            g.fillRect(area.x, area.y, area.width, area.height);
            g.setColor(new Color(80, 80, 120, 200));
            g.drawRect(area.x, area.y, area.width, area.height);
        }

        // 绘制路径（严格对齐网格）
        g.setStroke(new BasicStroke(PATH_WIDTH));
        g.setColor(new Color(100, 70, 40));
        for (int i = 0; i < pathPoints.size() - 1; i++) {
            Point p1 = pathPoints.get(i);
            Point p2 = pathPoints.get(i+1);
            // 对齐到网格中心
            int x1 = (int)(Math.floor(p1.x / (double)GRID_SIZE) * GRID_SIZE) + GRID_SIZE/2;
            int y1 = (int)(Math.floor(p1.y / (double)GRID_SIZE) * GRID_SIZE) + GRID_SIZE/2;
            int x2 = (int)(Math.floor(p2.x / (double)GRID_SIZE) * GRID_SIZE) + GRID_SIZE/2;
            int y2 = (int)(Math.floor(p2.y / (double)GRID_SIZE) * GRID_SIZE) + GRID_SIZE/2;
            g.drawLine(x1, y1, x2, y2);
        }

        // 绘制路径点标记
        g.setStroke(new BasicStroke(3));
        g.setColor(Color.YELLOW);
        for (Point p : pathPoints) {
            g.fillOval(p.x - 5, p.y - 5, 10, 10);
        }

        // 绘制建造预览
        if (gamePanel.isBuilding && gamePanel.previewTower != null) {
            int gridX = (int)Math.floor(gamePanel.previewTower.x / (double)GRID_SIZE) * GRID_SIZE;
            int gridY = (int)Math.floor(gamePanel.previewTower.y / (double)GRID_SIZE) * GRID_SIZE;

            g.setColor(isBuildable(gamePanel.previewTower.x, gamePanel.previewTower.y) 
                ? new Color(100, 255, 100, 80) 
                : new Color(255, 100, 100, 80));
            g.fillRect(gridX, gridY, GRID_SIZE, GRID_SIZE);
        }
    }
}